﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_CL_KERNEL_H
#define _UXS_CL_KERNEL_H

#pragma once

#include "CLProgram.h"
#include "CLQueue.h"

namespace UX_STL
{
namespace CLShell
{

	//
	// CL Kernel
	//

	class UX_EXPORT CLKernel : public CLBaseObject
	{
	protected:
		CLProgram	*	_pProgram;
		cl_kernel		_pID;
		
	protected:
		virtual void _RetainRef()  const;
		virtual void _ReleaseRef() const;
		virtual uint _GetRefCount()	const;
		virtual void _Destroy();

	public:
		CLKernel();
		~CLKernel();

		bool Create(CLProgram *pProg, uni_c_string pName);
		bool Create(CLProgram *pProg, cl_kernel pKernel);
		virtual void  Destroy();

		bool  GetFuncName(string &sName) const;
		uint  GetNumArgs() const;

		template <typename T>
		void  SetArg(cl_uint index, const T &arg) const;

		template <typename T>
		void  SetArg(cl_uint index, const T *args, uint count) const;

		CLProgram	*	Program()	const	{ return _pProgram; }
		cl_kernel		Id()		const	{ return _pID; }
	};

	
	
/*
=================================================
	передать значение в функцию ядра
=================================================
*/
	template <typename T>
	inline void CLKernel::SetArg(cl_uint index, const T &arg) const
	{
		CHECK_ERR( _pID != null, void() );
		CL_CALL( cl_int  i_cl_err = clSetKernelArg( _pID, index, sizeof(arg), (void *)&arg ) );
	}

/*
=================================================
	передать значения в функцию ядра
=================================================
*/
	template <typename T>
	inline void CLKernel::SetArg(cl_uint index, const T *args, uint count) const
	{
		CHECK_ERR( _pID != null and args != null and count != 0, void() );
		CL_CALL( cl_int  i_cl_err = clSetKernelArg( _pID, index, sizeof(T)*count, (void *)args ) );
	}

//-------------------------------------------------------------------

}	// CLShell
}	// UX_STL

#endif	// _UXS_CL_KERNEL_H